<?php

class Composite_Page_Main_Exception extends Page_Exception {}
class Composite_Page_Main_Invalid_Exception extends Composite_Page_Main_Exception {}

class Composite_Page_Main_Main {

	public function __construct($component, $parent){
		$this->page = $parent;
		$this->component = $component;
	}

	public function data_set($data){
		$this->page->parent()->data_set($data);
	}

	public function data_all(){
		return $this->page->parent()->data_all();
	}

	public function data_top(){
		return $this->page->parent()->data_top();
	}

	public function data_shift(){
		$this->page->parent()->data_shift();
	}

	public function URL($array = array()){
		return $this->page->URL(array_merge(
			array($this->component->id()),
			$array
		));
	}

}

class Composite_Page_Main_Aux {

	public function __construct($component, $parent){
		$this->page = $parent;
		$this->component = $component;
		$this->data = array();
	}

	public function data_set($data){
		$this->data = $data;
	}

	public function data_all(){
		return $this->data;
	}

	public function data_top(){
		return isset($this->data[0]) ? $this->data[0] : null;
	}

	public function data_shift(){
		array_shift($this->data);
	}

	public function URL(){
		return $this->page->URL(array_merge(
			array($this->component->id()),
			$array
		));
	}

}

class Composite_Page_Main extends Page_Main {

	public function parent(){
		return $this->parent;
	}

	public function __construct($args){
		parent::__construct($args);

		$this->composite = Composite::GetByID($args['id']);

		$components = $this->composite->getComponents();

		$this->components = array();

		foreach($components as $component){
			$a = $component->order();
			$b = $component->id();

			$edata = explode('/',$component->component());
			try {
				if(((int) $args['parent']->data_top()) == ((int) $component->id())){
					$d = $args['parent']->data_all();
					try {
						$args['parent']->data_shift();
						$this->components[$a][$b] = Page_Main::Get(implode('/', $args['parent']->data_all()), new Composite_Page_Main_Main($component, $this));
					} catch (Exception $e){
						$args['parent']->data_set($d);
						$this->components[$a][$b] = Page_Main::Get($component->component(), new Composite_Page_Main_Aux($component, $this));
					}
				} else {
					$this->components[$a][$b] = Page_Main::Get($component->component(), new Composite_Page_Main_Aux($component, $this));
				}
			} catch (Exception $e){
				unset($this->components[$a][$b]);
			}
		}
	
		ksort($this->components);

	}

	public function run(){
		parent::run();
		foreach($this->components as $order){
			foreach($order as $id){
				$id->run();
			}
		}
	}

	public function output($child = null){
		$template = Output::getInstance()->Template(array('composite','page'));
		if(isset($child)){
			$template->mode = $child;
		}
		foreach($this->components as $order){
			foreach($order as $id){
				$template->components[] = $id->output();
			}
		}
		return parent::output($template);
	}

	public function URL($array = array()){
		return parent::URL(array_merge(
			array('composite', $this->composite->id()),
			$array
		));
	}

	public function rid($array = array()){
		return array_merge(
			array('composite', $this->composite->id()),
			$array
		);
	}

	public static function Load($args){
		if((int) $args['parent']->data_top() != 0){
			$args['id'] = (int) $args['parent']->data_top();
			$args['parent']->data_shift();
			$page = new Composite_Page_Main($args);
			return $page;
		}
		throw new Composite_Page_Main_Invalid_Exception($args);
	}

}
